<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>AI 聊天助手</title>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/marked/11.1.1/marked.min.js"></script>
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/styles/github-dark.min.css">
    <script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/highlight.min.js"></script>
    <link rel="stylesheet" href="/static/css/chat.css" />
    <style>
        /* 工具按钮紧凑样式 */
        .tool-buttons {
            display: flex;
            flex-wrap: wrap;
            gap: 4px;
            margin-top: 6px;
            padding-top: 6px;
            border-top: 1px solid rgba(0, 0, 0, 0.06);
        }

        .tool-btn {
            display: inline-flex;
            align-items: center;
            padding: 2px 8px;
            font-size: 11px;
            line-height: 1.4;
            background: linear-gradient(135deg, #81acaf 100%, #81acaf 100%);
            color: white;
            border: none;
            border-radius: 10px;
            cursor: default;
            white-space: nowrap;
            font-weight: 500;
            letter-spacing: 0.2px;
            box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1);
            transition: all 0.2s ease;
        }

        .tool-btn:hover {
            transform: translateY(-1px);
            box-shadow: 0 2px 4px rgba(0, 0, 0, 0.15);
        }

        .tool-btn::before {
            content: '🔗';
            font-size: 10px;
            margin-right: 4px;
        }

        /* 深色模式适配 */
        @media (prefers-color-scheme: dark) {
            .tool-buttons {
                border-top-color: rgba(255, 255, 255, 0.1);
            }
            
            .tool-btn {
                background: linear-gradient(135deg, #5a67d8 0%, #6b46c1 100%);
                box-shadow: 0 1px 2px rgba(0, 0, 0, 0.3);
            }
            
            .tool-btn:hover {
                box-shadow: 0 2px 4px rgba(0, 0, 0, 0.4);
            }
        }
    </style>
</head>
<body>
    <div class="app-container">
        <div class="sidebar">
            <div class="sidebar-header">
                <button class="new-chat-btn" onclick="createNewChat()">
                    <span>➕</span> 新建对话
                </button>
            </div>
            <div class="history-list" id="historyList">
                <div class="empty-state">暂无历史记录</div>
            </div>
        </div>

        <div class="main-content">
            <div class="chat-header">
                <div>
                    <h1>AI 聊天助手</h1>
                    <div class="thread-id">会话 ID: <span id="threadId"></span></div>
                </div>
                <div class="header-actions">
                    <button class="btn btn-clear" onclick="clearCurrentHistory()">清除当前对话</button>
                </div>
            </div>

            <div class="chat-messages" id="chatMessages"></div>

            <div class="chat-input-container">
                <form class="chat-input-form" onsubmit="sendMessage(event)">
                    <textarea 
                        class="chat-input" 
                        id="messageInput" 
                        placeholder="输入消息... (Shift+Enter 换行，Enter 发送)" 
                        rows="1"
                        autocomplete="off"
                        required
                    ></textarea>
                    <button type="submit" class="btn-send" id="sendButton">发送</button>
                </form>
            </div>
        </div>
    </div>

    <script>
        marked.setOptions({
            highlight: (code, lang) => lang && hljs.getLanguage(lang) 
                ? hljs.highlight(code, { language: lang }).value 
                : hljs.highlightAuto(code).value,
            breaks: true,
            gfm: true
        });

        const MAX_MESSAGES = 100;
        const MAX_THREADS = 20;
        const chatMessages = document.getElementById('chatMessages');
        const messageInput = document.getElementById('messageInput');
        const sendButton = document.getElementById('sendButton');
        
        let threadId = null;
        let isStreaming = false;
        let allThreads = {};
        let currentAssistantDiv = null;
        let currentMessageText = '';

        // ========== 初始化 ==========
        function init() {
            allThreads = JSON.parse(localStorage.getItem('all_threads') || '{}');
            threadId = localStorage.getItem('current_thread_id');
            threadId ? loadThread(threadId) : createNewChat();
            renderHistoryList();
        }

        // ========== 线程管理 ==========
        function createNewChat() {
            threadId = 'thread_' + Date.now() + '_' + Math.random().toString(36).substr(2, 9);
            allThreads[threadId] = { 
                id: threadId, 
                title: '新对话', 
                createdAt: new Date().toISOString(), 
                messages: [] 
            };
            saveThreads();
            setThread(threadId);
            chatMessages.innerHTML = '';
            addMessage('assistant', '你好！我是 AI 助手，有什么可以帮助你的吗？');
            renderHistoryList();
        }

        function setThread(id) {
            threadId = id;
            localStorage.setItem('current_thread_id', id);
            document.getElementById('threadId').textContent = id || '未选择';
        }

        function loadThread(id) {
            const thread = allThreads[id];
            if (!thread) return;
            setThread(id);
            chatMessages.innerHTML = '';
            
            if (!thread.messages.length) {
                addMessage('assistant', '你好！我是 AI 助手，有什么可以帮助你的吗？');
                return;
            }

            let lastAssistantDiv = null;
            thread.messages.slice(-MAX_MESSAGES).forEach(msg => {
                if (msg.role === 'assistant') {
                    lastAssistantDiv = addMessage('assistant', msg.content, true, false);
                } else if (msg.role === 'tool' && lastAssistantDiv) {
                    addToolButtons(lastAssistantDiv, msg.content);
                } else if (msg.role === 'user') {
                    addMessage('user', msg.content, false, false);
                    lastAssistantDiv = null;
                }
            });
        }

        function deleteThread(id) {
            if (!confirm('确定要删除这个对话吗？')) return;
            delete allThreads[id];
            saveThreads();
            if (threadId === id) {
                const remaining = Object.keys(allThreads);
                remaining.length ? loadThread(remaining[0]) : createNewChat();
            }
            renderHistoryList();
        }

        function clearCurrentHistory() {
            if (!confirm('确定要清除当前对话的所有消息吗？')) return;
            allThreads[threadId].messages = [];
            saveThreads();
            loadThread(threadId);
        }

        function saveThreads() {
            const ids = Object.keys(allThreads);
            if (ids.length > MAX_THREADS) {
                ids.sort((a, b) => new Date(allThreads[a].createdAt) - new Date(allThreads[b].createdAt))
                   .slice(0, ids.length - MAX_THREADS)
                   .forEach(id => delete allThreads[id]);
            }
            localStorage.setItem('all_threads', JSON.stringify(allThreads));
        }

        // ========== UI 渲染 ==========
        function renderHistoryList() {
            const historyList = document.getElementById('historyList');
            const threads = Object.values(allThreads)
                .sort((a, b) => new Date(b.createdAt) - new Date(a.createdAt));
            
            if (!threads.length) {
                historyList.innerHTML = '<div class="empty-state">暂无历史记录</div>';
                return;
            }

            historyList.innerHTML = threads.map(thread => {
                const date = new Date(thread.createdAt).toLocaleDateString('zh-CN', { 
                    month: '2-digit', day: '2-digit', hour: '2-digit', minute: '2-digit' 
                });
                const isActive = thread.id === threadId ? 'active' : '';
                const title = escapeHtml(thread.title);
                return `
                    <div class="history-item ${isActive}" onclick="loadThread('${thread.id}'); renderHistoryList();">
                        <div class="history-item-title">${title}</div>
                        <div class="history-item-date">${date}</div>
                        <div class="history-item-actions" onclick="event.stopPropagation()">
                            <button class="history-item-btn delete" onclick="deleteThread('${thread.id}')">删除</button>
                        </div>
                    </div>
                `;
            }).join('');
        }

        function addMessage(role, content, isMarkdown = false, persist = true) {
            while (chatMessages.children.length >= MAX_MESSAGES) {
                chatMessages.removeChild(chatMessages.firstChild);
            }

            const messageDiv = document.createElement('div');
            messageDiv.className = `message ${role}`;
            
            const contentDiv = document.createElement('div');
            contentDiv.className = 'message-content';
            
            if (isMarkdown && role === 'assistant') {
                contentDiv.innerHTML = marked.parse(content);
                addCopyButtons(contentDiv);
            } else {
                contentDiv.textContent = content;
            }

            if (role === 'assistant') {
                messageDiv.appendChild(createAvatar('AI', 'ai'));
                messageDiv.appendChild(contentDiv);
            } else {
                messageDiv.appendChild(contentDiv);
                messageDiv.appendChild(createAvatar('你', 'user'));
            }

            chatMessages.appendChild(messageDiv);
            chatMessages.scrollTop = chatMessages.scrollHeight;

            if (persist && allThreads[threadId]) {
                allThreads[threadId].messages.push({ role, content });
                if (role === 'user' && allThreads[threadId].title === '新对话') {
                    allThreads[threadId].title = content.substring(0, 30) + (content.length > 30 ? '...' : '');
                    renderHistoryList();
                }
                saveThreads();
            }

            return contentDiv;
        }

        function addToolButtons(contentDiv, toolContent) {
            let toolZone = contentDiv.querySelector('.tool-buttons');
            if (!toolZone) {
                toolZone = document.createElement('div');
                toolZone.className = 'tool-buttons';
                contentDiv.appendChild(toolZone);
            }

            const tools = toolContent.trim().split(/[,，\n]/).map(s => s.trim()).filter(Boolean);
            (tools.length ? tools : ['工具调用']).forEach(label => {
                const btn = document.createElement('button');
                btn.type = 'button';
                btn.className = 'tool-btn';
                btn.textContent = label;
                toolZone.appendChild(btn);
            });

            chatMessages.scrollTop = chatMessages.scrollHeight;
        }

        function createAvatar(text, className) {
            const avatar = document.createElement('div');
            avatar.className = `avatar ${className}`;
            avatar.textContent = text;
            avatar.title = text;
            return avatar;
        }

        function addCopyButtons(element) {
            element.querySelectorAll('pre').forEach(pre => {
                const wrapper = document.createElement('div');
                wrapper.className = 'code-block-wrapper';
                pre.parentNode.insertBefore(wrapper, pre);
                wrapper.appendChild(pre);
                
                const button = document.createElement('button');
                button.className = 'copy-button';
                button.textContent = '复制';
                button.onclick = () => {
                    navigator.clipboard.writeText(pre.querySelector('code').textContent).then(() => {
                        button.textContent = '已复制!';
                        button.classList.add('copied');
                        setTimeout(() => {
                            button.textContent = '复制';
                            button.classList.remove('copied');
                        }, 2000);
                    });
                };
                wrapper.appendChild(button);
            });
        }

        function updateStreamingMessage(contentDiv, text) {
            const toolZone = contentDiv.querySelector('.tool-buttons');
            const toolZoneClone = toolZone ? toolZone.cloneNode(true) : null;
            
            contentDiv.innerHTML = marked.parse(text);
            addCopyButtons(contentDiv);
            
            if (toolZoneClone) {
                contentDiv.appendChild(toolZoneClone);
            }
            
            chatMessages.scrollTop = chatMessages.scrollHeight;
        }

        function escapeHtml(text) {
            const div = document.createElement('div');
            div.textContent = text;
            return div.innerHTML;
        }

        // ========== 消息发送 ==========
        async function sendMessage(event) {
            event.preventDefault();
            if (isStreaming) return;
            
            const message = messageInput.value.trim();
            if (!message) return;

            addMessage('user', message);
            messageInput.value = '';
            messageInput.style.height = 'auto';

            isStreaming = true;
            sendButton.disabled = true;
            sendButton.textContent = '发送中...';

            currentAssistantDiv = null;
            currentMessageText = '';
            const sessionTools = [];

            try {
                const response = await fetch('api/v1/chat/stream', {
                    method: 'POST',
                    headers: { 'Content-Type': 'application/json' },
                    body: JSON.stringify({ message, thread_id: threadId })
                });

                if (!response.ok) throw new Error('请求失败');

                const reader = response.body.getReader();
                const decoder = new TextDecoder();

                while (true) {
                    const { done, value } = await reader.read();
                    if (done) break;

                    const lines = decoder.decode(value).split('\n');
                    for (const line of lines) {
                        if (!line.startsWith('data: ')) continue;

                        const data = JSON.parse(line.slice(6));

                        if (data.type === 'message') {
                            if (!currentAssistantDiv) {
                                currentAssistantDiv = addMessage('assistant', '', false, false);
                            }
                            currentMessageText += data.content;
                            updateStreamingMessage(currentAssistantDiv, currentMessageText);
                        } 
                        else if (data.type === 'tool') {
                            if (!currentAssistantDiv) {
                                currentAssistantDiv = addMessage('assistant', '', false, false);
                            }
                            addToolButtons(currentAssistantDiv, data.content);
                            sessionTools.push({ role: 'tool', content: data.content });
                        } 
                        else if (data.type === 'done') {
                            if (allThreads[threadId]) {
                                if (currentMessageText) {
                                    allThreads[threadId].messages.push({ 
                                        role: 'assistant', 
                                        content: currentMessageText 
                                    });
                                }
                                sessionTools.forEach(tool => allThreads[threadId].messages.push(tool));
                                saveThreads();
                            }
                            currentAssistantDiv = null;
                            currentMessageText = '';
                        } 
                        else if (data.type === 'error') {
                            addMessage('assistant', '抱歉，发生了错误：' + data.content);
                        }
                    }
                }
            } catch (error) {
                console.error('Error:', error);
                addMessage('assistant', '抱歉，发生了错误。请稍后重试。');
            } finally {
                isStreaming = false;
                sendButton.disabled = false;
                sendButton.textContent = '发送';
            }
        }

        // ========== 事件监听 ==========
        messageInput.addEventListener('keydown', (e) => {
            if (e.key === 'Enter' && !e.shiftKey) {
                e.preventDefault();
                sendMessage(e);
            }
        });

        messageInput.addEventListener('input', function() {
            this.style.height = 'auto';
            this.style.height = Math.min(this.scrollHeight, 150) + 'px';
        });

        init();
    </script>
</body>
</html>